import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.preprocessing import MinMaxScaler, StandardScaler
%matplotlib inline
print('numpy version : ',np.__version__)
print('pandas version : ',pd.__version__)
print('seaborn version : ',sns.__version__)
numpy version : 1.19.4 pandas version : 1.2.3 seaborn version : 0.11.2
df = pd.read_csv('dataset.csv')
df
| Administrative | Administrative_Duration | Informational | Informational_Duration | ProductRelated | ProductRelated_Duration | BounceRates | ExitRates | PageValues | SpecialDay | Month | OperatingSystems | Browser | Region | TrafficType | VisitorType | Weekend | Revenue | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.0 | 0.000000 | 0 | 0.0 | 1 | 0.000000 | 0.200000 | 0.200000 | 0.0 | 0.0 | Feb | 1.0 | 1 | 1 | 1 | Returning_Visitor | False | False |
| 1 | 0.0 | 0.000000 | 0 | 0.0 | 2 | 64.000000 | 0.000000 | 0.100000 | 0.0 | 0.0 | Feb | 2.0 | 2 | 1 | 2 | Returning_Visitor | False | False |
| 2 | 0.0 | 0.000000 | 0 | 0.0 | 1 | 0.000000 | 0.200000 | 0.200000 | 0.0 | 0.0 | Feb | 4.0 | 1 | 9 | 3 | Returning_Visitor | False | False |
| 3 | 0.0 | NaN | 0 | 0.0 | 2 | 2.666667 | 0.050000 | 0.140000 | 0.0 | 0.0 | Feb | 3.0 | 2 | 2 | 4 | Returning_Visitor | False | False |
| 4 | 0.0 | 0.000000 | 0 | 0.0 | 10 | 627.500000 | 0.020000 | 0.050000 | 0.0 | 0.0 | Feb | 3.0 | 3 | 1 | 4 | Returning_Visitor | True | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 12941 | 0.0 | 0.000000 | 0 | 0.0 | 2 | 0.000000 | 0.200000 | 0.200000 | 0.0 | 0.0 | Nov | 3.0 | 2 | 1 | 13 | Returning_Visitor | False | False |
| 12942 | 0.0 | 0.000000 | 0 | 0.0 | 59 | 1309.658333 | 0.017241 | 0.030879 | 0.0 | 0.0 | Dec | 3.0 | 2 | 3 | 1 | Returning_Visitor | False | False |
| 12943 | 14.0 | 484.461579 | 2 | 14.0 | 33 | 898.491579 | 0.004269 | 0.034661 | 0.0 | 0.0 | Sep | 1.0 | 8 | 1 | 3 | Returning_Visitor | False | False |
| 12944 | 3.0 | 60.833333 | 0 | 0.0 | 18 | 884.633333 | 0.021053 | 0.041140 | 0.0 | 0.0 | Mar | 2.0 | 2 | 3 | 10 | Returning_Visitor | False | False |
| 12945 | 0.0 | 0.000000 | 0 | 0.0 | 6 | 241.000000 | 0.000000 | 0.033333 | 0.0 | 0.0 | May | 2.0 | 10 | 2 | 3 | Returning_Visitor | False | False |
12946 rows × 18 columns
A. Apakah ada kolom dengan tipe data kurang sesuai, atau nama kolom dan isinya kurang sesuai?
B. Apakah ada kolom yang memiliki nilai kosong? Jika ada, apa saja?
C. Apakah ada kolom yang memiliki nilai summary agak aneh? (min/mean/median/max/unique/top/freq)
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 12946 entries, 0 to 12945 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Administrative 12835 non-null float64 1 Administrative_Duration 12313 non-null float64 2 Informational 12946 non-null int64 3 Informational_Duration 12946 non-null float64 4 ProductRelated 12946 non-null int64 5 ProductRelated_Duration 12307 non-null float64 6 BounceRates 12872 non-null float64 7 ExitRates 12946 non-null float64 8 PageValues 12946 non-null float64 9 SpecialDay 12946 non-null float64 10 Month 12946 non-null object 11 OperatingSystems 12422 non-null float64 12 Browser 12946 non-null int64 13 Region 12946 non-null int64 14 TrafficType 12946 non-null int64 15 VisitorType 12946 non-null object 16 Weekend 12946 non-null bool 17 Revenue 12946 non-null bool dtypes: bool(2), float64(9), int64(5), object(2) memory usage: 1.6+ MB
kategori = ['OperatingSystems', 'Browser', 'Region', 'TrafficType', 'VisitorType', 'Weekend', 'Revenue']
numerikal = ['Administrative', 'Administrative_Duration', 'Informational', 'Informational_Duration',
'ProductRelated', 'ProductRelated_Duration', 'BounceRates', 'ExitRates', 'PageValues','SpecialDay']
date = ['Month']
data dibagi menjadi 3 tipe, yaitu kategori, numerik, dan date
Terdapat beberapa tipe data yang kurang sesuai, seperti Region, traffictype, browser, operating system yang harusnya bertipe data object. Bisa diganti tipe datanya saat praproses data.
df[kategori].astype('object').describe()
| OperatingSystems | Browser | Region | TrafficType | VisitorType | Weekend | Revenue | |
|---|---|---|---|---|---|---|---|
| count | 12422.0 | 12946 | 12946 | 12946 | 12946 | 12946 | 12946 |
| unique | 8.0 | 13 | 9 | 20 | 3 | 2 | 2 |
| top | 2.0 | 2 | 1 | 2 | Returning_Visitor | False | False |
| freq | 6673.0 | 8360 | 5031 | 4100 | 11072 | 9929 | 10938 |
Data seperti operating system, browser, region, dan traffic type memiliki label yang kurang jelas. Bisa ditambahkan penjelasan label tersebut.
df[numerikal].describe()
| Administrative | Administrative_Duration | Informational | Informational_Duration | ProductRelated | ProductRelated_Duration | BounceRates | ExitRates | PageValues | SpecialDay | |
|---|---|---|---|---|---|---|---|---|---|---|
| count | 12835.000000 | 12313.000000 | 12946.000000 | 12946.000000 | 12946.000000 | 12307.000000 | 12872.000000 | 12946.000000 | 12946.000000 | 12946.000000 |
| mean | 2.303857 | 80.370267 | 0.498841 | 34.136048 | 31.657655 | 1192.740077 | 0.022309 | 0.043266 | 5.875963 | 0.061270 |
| std | 3.314427 | 175.494016 | 1.263276 | 140.022848 | 44.202635 | 1910.216261 | 0.048681 | 0.048808 | 18.414670 | 0.198667 |
| min | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 25% | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 7.000000 | 182.083333 | 0.000000 | 0.014286 | 0.000000 | 0.000000 |
| 50% | 1.000000 | 7.000000 | 0.000000 | 0.000000 | 18.000000 | 599.583333 | 0.003112 | 0.025329 | 0.000000 | 0.000000 |
| 75% | 4.000000 | 92.933333 | 0.000000 | 0.000000 | 38.000000 | 1470.522917 | 0.016933 | 0.050000 | 0.000000 | 0.000000 |
| max | 27.000000 | 3398.750000 | 24.000000 | 2549.375000 | 705.000000 | 63973.522230 | 0.200000 | 0.200000 | 361.763742 | 1.000000 |
Beberapa data memiliki nilai mean yang sangat melebihi nilai mediannya. Hal ini dikarenakan fitur memiliki nilai outlier yang ekstrim.
df.isna().sum()
Administrative 111 Administrative_Duration 633 Informational 0 Informational_Duration 0 ProductRelated 0 ProductRelated_Duration 639 BounceRates 74 ExitRates 0 PageValues 0 SpecialDay 0 Month 0 OperatingSystems 524 Browser 0 Region 0 TrafficType 0 VisitorType 0 Weekend 0 Revenue 0 dtype: int64
ada lima kolom yang mengandung nilai null, yaitu :
untuk tipe data numerik, data yang bersifat null akan diisi dengan nilai median. Hal ini dikarenakan ada outlier yang sangat ekstrim sehingga nilai mean berada jauh diaatas median.
untuk tipe data kategorik, data bisa didrop karena tidak terlalu memengaruhi analisis datanya.
df.duplicated().sum()
711
Ada 711 baris data yang duplikat. Data yang duplikat bisa dihapus dan disisakan data paling awal muncul saat praproses data.
plt.figure(figsize=(8, 8))
for i in range(0,len(numerikal)):
plt.subplot(2,5,i+1)
sns.boxplot(y=df[numerikal[i]],orient='v')
plt.tight_layout()
hampir semua data numerik memiliki kasus outlier yang cukup ekstrim. Data outliers ini bisa kita hapus menggunakan teknik z-score atau IQR.
plt.figure(figsize=(8, 8))
for i in range(0,len(numerikal)):
plt.subplot(2,5,i+1)
sns.violinplot(y=df[numerikal[i]])
plt.tight_layout()
plt.figure(figsize=(12, 8))
for i in range(0,len(numerikal)):
plt.subplot(4,3,i+1)
sns.kdeplot(x=df[numerikal[i]],color='green')
plt.xlabel(numerikal[i])
plt.tight_layout()
Semua data numerik memiliki nilai outlier yang tinggi di sebelah kanan. Hal ini membuat nilai mean menjadi tinggi sehingga menyebabkan grafik right-skewed.
cat = ['Weekend', 'Revenue']
plt.figure(figsize=(10, 8))
for i in range(0,len(cat)):
plt.subplot(1,len(cat),i+1)
ax = sns.countplot(x=df[cat[i]].astype('object'))
for p in ax.patches:
ax.annotate(f'{p.get_height()}', (p.get_x() + p.get_width() / 2., p.get_height()),
ha='center', va='center', xytext=(0, 10), textcoords='offset points')
cat2 = ['VisitorType','OperatingSystems', 'Browser', 'Region', 'TrafficType','Month']
plt.figure(figsize=(12, 15))
for i in range(0,len(cat2)):
plt.subplot(3,2,i+1)
sns.countplot(y=df[cat2[i]].astype('object'),order = df[cat2[i]].astype('object').value_counts().index)
Untuk tipe kategorik, berikut adalah data dengan jumlah terbanyak :
beberapa data memiliki count yang sangat kecil sehingga tidak muncul di graph seperti :
data ini memiliki potensi untuk didrop
df_cat = df[kategori]
# df_cat = df_cat.astype('object')
plt.figure(figsize=(10, 8))
for i in range(0,len(kategori)):
plt.subplot(4, 2, i+1)
sns.countplot(data=df_cat,x=kategori[i],hue='Revenue')
plt.tight_layout()
mult = ['Administrative', 'Administrative_Duration', 'Informational', 'Informational_Duration', 'ProductRelated', 'ProductRelated_Duration', 'BounceRates', 'ExitRates', 'PageValues','SpecialDay','Revenue']
plt.figure(figsize=(8, 8))
sns.heatmap(df[mult].corr(),cmap='Blues',annot=True,fmt='.2f')
<AxesSubplot:>
Dari correlation heatmap diatas, ada beberapa info yang bisa kita ambil :
Kita bisa men-drop salah satu fitur yang memiliki relasi yang kuat. Untuk mengetahui mana fitur yang didrop, bisa dilihat relasi fitur tersebut dengan fitur dependantnya (revenue).
plt.figure(figsize=(15, 15))
sns.pairplot(df[mult], diag_kind='kde',hue='Revenue')
<seaborn.axisgrid.PairGrid at 0x24cd7c25640>
<Figure size 1500x1500 with 0 Axes>
plt.figure(figsize=(15, 15))
for i in range(0, len(numerikal)):
plt.subplot(4, 3, i+1)
sns.stripplot(data=df, x='VisitorType', y=numerikal[i],hue='Revenue')
plt.tight_layout()
plt.figure(figsize=(15, 15))
for i in range(0, len(numerikal)):
plt.subplot(4, 3, i+1)
sns.stripplot(data=df, x='Weekend', y=numerikal[i],hue='Revenue')
plt.tight_layout()
Di weekdays,
conversion_rate_visitor = df.groupby('VisitorType')['Revenue'].mean().reset_index()
df['VisitorType'].value_counts()
Returning_Visitor 11072 New_Visitor 1785 Other 89 Name: VisitorType, dtype: int64
plt.subplot(2, 1, 1)
sns.countplot(data=df_cat,y='VisitorType',hue='Revenue')
plt.subplot(2,1,2)
sns.barplot(data=conversion_rate_visitor, y='VisitorType',x='Revenue')
plt.tight_layout()
Nilai conversion rate tertinggi (24,64%) berasal dari new visitor padahal kunjungan tertinggi (11.072 kunjungan) berasal dari returning visitor. Hal ini menunjukkan bahwa lebih banyak new visitor yang melakukan pembelian daripada returning visitor.
Business Recommendation:
Perusahaan perlu mempelajari hal-hal atau strategi apa saja yang sudah efektif dalam menarik pelanggan baru sebelumnya agar bisa ditingkatkan lagi. Selain itu, perlu dilakukan analisa data perilaku returning visitor untuk mengetahui lebih jauh alasan mereka melakukan pembelian atau tidak. Perusahaan juga bisa menawarkan promo-promo untuk pembeli yang melakukan repeat order atau program loyalty agar bisa meningkatkan minat pembelian pada returning visitor.
conversion_rate_weekend = df.groupby('Weekend')['Revenue'].mean().reset_index()
df['Weekend'].value_counts()
False 9929 True 3017 Name: Weekend, dtype: int64
plt.subplot(1, 2, 1)
sns.countplot(data=df_cat,x='Weekend',hue='Revenue')
plt.subplot(1,2,2)
sns.barplot(data=conversion_rate_weekend, x='Weekend',y='Revenue')
plt.title('Conversion Rate')
plt.tight_layout()
conversion_rate_month = df.groupby('Month')['Revenue'].mean().reset_index()
df['Month'].value_counts()
May 3533 Nov 3151 Mar 1997 Dec 1816 Oct 574 Sep 464 Aug 461 Jul 451 June 308 Feb 191 Name: Month, dtype: int64
plt.subplot(2, 1, 1)
sns.countplot(data=df,x='Month',hue='Revenue')
plt.subplot(2,1,2)
sns.barplot(data=conversion_rate_month, x='Month',y='Revenue')
plt.title('Conversion Rate')
plt.tight_layout()
conversion_rate_os = df.groupby('OperatingSystems')['Revenue'].mean().reset_index()
df['OperatingSystems'].value_counts()
2.0 6673 1.0 2590 3.0 2571 4.0 480 8.0 78 6.0 17 7.0 7 5.0 6 Name: OperatingSystems, dtype: int64
plt.subplot(2, 1, 1)
sns.countplot(data=df_cat,x='OperatingSystems',hue='Revenue')
plt.subplot(2,1,2)
sns.barplot(data=conversion_rate_os, x='OperatingSystems',y='Revenue')
plt.title('Conversion Rate')
plt.tight_layout()
conversion_rate_browser = df.groupby('Browser')['Revenue'].mean().reset_index()
df['Browser'].value_counts()
2 8360 1 2570 4 780 5 496 6 180 10 172 8 143 3 114 13 65 7 49 12 10 11 6 9 1 Name: Browser, dtype: int64
plt.subplot(2, 1, 1)
sns.countplot(data=df_cat,x='Browser',hue='Revenue')
plt.subplot(2,1,2)
sns.barplot(data=conversion_rate_browser, x='Browser',y='Revenue')
plt.title('Conversion Rate')
plt.tight_layout()
conversion_rate_region = df.groupby('Region')['Revenue'].mean().reset_index()
plt.subplot(2, 1, 1)
sns.countplot(data=df_cat,x='Region',hue='Revenue')
plt.subplot(2,1,2)
sns.barplot(data=conversion_rate_region, x='Region',y='Revenue')
plt.title('Conversion Rate')
plt.tight_layout()
Berdasarkan Grafik diatas diketahui bahwa mayoritas dari penggunjung berasal dari 3 kota besar yaitu kota 1, 3, 4. Sehingga, untuk meningkatkan nilai conversion rate, kita dapat memprioritaskan untuk melakukan promosi di kota-kota tersebut.
sns.countplot(data=df,x='Month',hue='VisitorType')
<AxesSubplot:xlabel='Month', ylabel='count'>